package com.gitee.huanminabc.multimedia.ffmpeg;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FfmpegImageUtil {

    //修改图片大小
    public static void setWidthAndHeightImage(String inputPath, String outputPath, int width, int height) {
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("scale=" + width + ":" + height);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //修改图片大小,等比例缩放,这个需要根据图片的宽高进行计算 ,参数是百分比 ,比如200就是放大两倍,50就是缩小一半,放大到一定程度会导致图片失真
    public static void setWidthAndHeightImagePercent(String inputPath, String outputPath, int percent) {

        //获取图片的宽高
        int[] ints = FfmpegInfoUtil.GeWidthAndHeight(inputPath);
        int width = ints[0];
        int height = ints[1];
        //计算百分比
        int newWidth = width * percent / 100;
        int newHeight = height * percent / 100;
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("scale=" + newWidth + ":" + newHeight);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }


    /**
     * 给图片添加高斯模糊
     *
     * @param inputPath  图片路径
     * @param outputPath 输出路径
     * @param radius     模糊半径
     */
    public static void addGaussianBlur(String inputPath, String outputPath, int radius) {

        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("gblur=sigma=" + radius);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }


    //图片旋转,1是顺时针旋转90度,2是逆时针旋转90度,3是顺时针旋转180度
    public static void rotateImage(String inputPath, String outputPath, int rotate) {
        //判断输入
        if (rotate < 1 || rotate > 3) {
            throw new RuntimeException("rotate参数只能是1,2,3");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("transpose=" + rotate);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //图片进行翻转 ,0是水平翻转,1是垂直翻转
    public static void flipImage(String inputPath, String outputPath, int flip) {
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        if (flip == 0) {//水平翻转
            cmds.add("hflip");
        } else if (flip == 1) { //垂直翻转
            cmds.add("vflip");
        } else {
            throw new RuntimeException("flip参数只能是0,1");
        }
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //图片锐化, radius是锐化半径,0~5之间,越大锐化效果越明显,但是也会导致图片失真 ,0是不锐化
    public static void sharpenImage(String inputPath, String outputPath, double radius) {
        //radius只能在0~5之间
        if (radius < 0 || radius > 5) {
            throw new RuntimeException("radius参数只能在0~5之间");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("unsharp=5:5:"+radius+":5:5:0.0");
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //图像压缩 但是不会太影响画质 ,quality是压缩质量,0~100之间,越高压缩比越大,画质越差,0最好,100最差,根据实际情况调整
    // 一般高清分辨率 10~30就可以了 ,图形分辨率越小,压缩比需要越小,否则会导致图片失真
    public static void compressImage(String inputPath, String outputPath, int quality) {
        //quality
        if (quality < 0 || quality > 100) {
            throw new RuntimeException("quality参数只能在0~100之间");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-q:v");
        cmds.add(String.valueOf(quality));
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }





    /**
     * 将图片转换为目标格式
     * @param inputPath  原始图片路径: /cc/aa.jpg
     * @param outputPath 目标图片路径  /cc/aa.png
     */
    public static void convertToFormat(String inputPath, String outputPath) {
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }


    //改变图片透明度,opacity是透明度,0~100之间,0是完全透明,100是完全不透明
    //注意: 只支持png格式的输入图片,因为png格式支持透明度,其他格式不支持, 如果是其他格式那么没有效果
    //可以使用convertToFormat方法将图片转换为png格式
    public static void opacityImage(String inputPath, String outputPath, int opacity) {
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("format=rgba,colorchannelmixer=aa=" + opacity / 100.0);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //图像提亮和变暗 ,brighten是提亮的程度,-1~1之间,0是不提亮,1是完全提亮
    public static void brightenImage(String inputPath, String outputPath, double brighten) {
        if (brighten < -1 || brighten > 1) {
            throw new RuntimeException("brighten参数只能在-1~1之间");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("eq=brightness=" + brighten);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }
    //饱和度调整 ,saturation是饱和度,0~3之间,0是完全不饱和,3是完全饱和
    public static void saturationImage(String inputPath, String outputPath, double saturation) {
        if (saturation < 0 || saturation > 3) {
            throw new RuntimeException("saturation参数只能在0~3之间");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("eq=saturation=" + saturation);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //对比度调整 ,contrast是对比度, 1~3之间,1是不调整,3是最大对比度
    //正数表示更暗,负数表示更亮
    public static void contrastImage(String inputPath, String outputPath, double contrast) {
        if (contrast < 1 || contrast > 3) {
            throw new RuntimeException("contrast参数只能在1~3之间,虽然支持-1000~1000,但是一般不会这么大会导致图片直接变成黑白");
        }
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-y");
        cmds.add("-vf");
        cmds.add("eq=contrast=" + contrast);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }



    //给图像添加水印
    public static void addImageWatermark(String inputPath, String outputPath, String watermarkPath, int x, int y) {
        List<String> cmds = new ArrayList<>();
        cmds.add("-i");
        cmds.add(inputPath);
        cmds.add("-i");
        cmds.add(watermarkPath);
        cmds.add("-y");
        cmds.add("-filter_complex");
        cmds.add("overlay=" + x + ":" + y);
        cmds.add(outputPath);
        FfmpegInfoUtil.ExecuteCmd(cmds);
    }

    //给图像最右下角添加水印
    public static void addImageWatermark(String inputPath, String outputPath, String watermarkPath) {
        //获取图片的宽高
        int[] ints = FfmpegInfoUtil.GeWidthAndHeight(inputPath);
        int width = ints[0];
        int height = ints[1];
        //获取水印的宽高
        int[] ints1 = FfmpegInfoUtil.GeWidthAndHeight(watermarkPath);
        int watermarkWidth = ints1[0];
        int watermarkHeight = ints1[1];
        int x = width - watermarkWidth - 10;
        int y = height - watermarkHeight - 10;

        addImageWatermark(inputPath, outputPath, watermarkPath, x, y);
    }



}
